package com.ewzj.bigdata.mvp.presenter

import android.app.Application
import android.util.Base64
import android.util.Log
import com.ewzj.bigdata.app.config.AppKey
import com.ewzj.bigdata.app.extensions.DelegatesExt
import com.ewzj.bigdata.app.utils.MD5Utils
import com.ewzj.bigdata.app.utils.RxSocket
import com.ewzj.bigdata.app.utils.RxUtils
import com.ewzj.bigdata.mvp.contract.MapActivityContract
import com.ewzj.bigdata.mvp.model.reqbean.ReqmapChangeBean
import com.ewzj.bigdata.mvp.model.reqbean.Reqmaphomelist
import com.ewzj.bigdata.mvp.model.rspbean.BaseData
import com.ewzj.bigdata.mvp.model.rspbean.BaseListData
import com.ewzj.bigdata.mvp.model.rspbean.CityBean
import com.ewzj.bigdata.mvp.model.rspbean.HomeBean
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import com.jess.arms.mvp.BaseModel
import com.jess.arms.mvp.BasePresenter
import com.jess.arms.utils.DataHelper
import com.jess.arms.utils.DeviceUtils
import com.jess.arms.utils.UiUtils
import io.reactivex.Observable
import io.reactivex.functions.Consumer
import me.jessyan.rxerrorhandler.core.RxErrorHandler
import me.jessyan.rxerrorhandler.handler.ErrorHandleSubscriber
import org.json.JSONException
import org.json.JSONObject
import java.nio.ByteBuffer
import java.util.HashSet
import java.util.function.Predicate
import javax.inject.Inject
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import timber.log.Timber
import java.io.UnsupportedEncodingException
import java.net.URLEncoder


/**
 * author:zhangjing
 * 作用:
 * return:
 */
class MapActivityPresenter @Inject constructor(val application: Application,val mGson:Gson,val rxErrorHandler: RxErrorHandler,model:MapActivityContract.Model,view :MapActivityContract.View):BasePresenter<MapActivityContract.Model,MapActivityContract.View>(model,view){
    val socket by lazy { RxSocket.getInstance() }
    val ip = "139.129.116.71"
    val port:Int by lazy { AppKey.mappConfig.port }
    var builder: StringBuilder? = null
    var isfirst: Boolean = false
    var type = 1
    var maptype = 1
    var newreginBean: List<HomeBean>? = null
    var oldreginBean:List<HomeBean>? = null
    var rentreginBean:List<HomeBean>? = null
    //    地图上所有的房源列表
    var maphomeBeens: HashSet<Int> = HashSet()
    var savedcity:String by DelegatesExt.preference(application,AppKey.LOCATION_CITY,"")
    val currentCity:CityBean.ListEntity by lazy { mGson.fromJson(savedcity,CityBean.ListEntity::class.java) }

    fun socketConnect(){
        socket.connectRx(ip,port).compose(RxUtils.applySchedulers(mRootView))
                .subscribe(object :ErrorHandleSubscriber<Boolean>(rxErrorHandler){
                    override fun onNext(t: Boolean) {
                        if (t){
                            mRootView.init()
                            socketReadMsg()
                        }else{
                            UiUtils.SnackbarText("长链接失败，请稍后重试")
                        }

                    }

                })
    }

    fun socketSendMsg(reqmapChangeBean: ReqmapChangeBean){
//        city_id=63&house_type=xinfang&time=1504684438
        var time=System.currentTimeMillis().toString()
        var str="#city_id="+reqmapChangeBean.city_id+"&"+"house_type="+reqmapChangeBean.house_type+"&"+"time="+time.substring(0,time.length-3)
        reqmapChangeBean.time=time.substring(0,time.length-3)
        Timber.tag("sssssss").w(str)
        reqmapChangeBean.sign=MD5Utils.encryptStr(str)
        val msg=mGson.toJson(reqmapChangeBean)
        Timber.tag("sssssss").w(msg)
        val byteBuffer = ByteBuffer.wrap(msg.toByteArray())
        socket.write(byteBuffer).compose(RxUtils.applySchedulers(mRootView))
                .subscribe(object :ErrorHandleSubscriber<Boolean>(rxErrorHandler){
            override fun onNext(t: Boolean) {
                    if(!t){
                        UiUtils.SnackbarText("发送失败，请稍后重试")
                    }
            }

        })
    }

    fun socketReadMsg(){
        socket.read()
                .subscribe(object :ErrorHandleSubscriber<ByteArray>(rxErrorHandler){
                    override fun onNext(bytes: ByteArray) {
                        if (builder == null) {
                            isfirst = true
                            builder = StringBuilder(String(bytes))
                        } else {
                            builder!!.append(String(bytes))
                            isfirst = false
                        }
                        try {
                            mapMoveChange()
                        } catch (e: Exception) {
                            Timber.tag("========").w(e.toString())

                        }

                    }
                })
    }

    @Throws(JSONException::class)
    private fun mapMoveChange() {
        maptype = 2

        Timber.tag("dadaddada").w(builder.toString())
        if (!builder.toString().startsWith("{")){
            builder = null
            return
        }
        val jsonObject = JSONObject(builder.toString())
        //yes, 标准的json格式

        Timber.tag("--------").w(builder.toString())
        val datas = mGson.fromJson<BaseData<BaseListData<HomeBean>>>(builder.toString().trim(), object : TypeToken<BaseData<BaseListData<HomeBean>>>() {}.type)
        if (!datas.isSuccess()){
            builder = null
            UiUtils.SnackbarText(datas.msg)
            return
        }
        if (datas.data!!.list==null||datas.data!!.list.size==0){
            builder = null
            return
        }
        Observable.just(datas.data!!.list).map { t1 ->t1.apply{
            if (datas.data!!.list.size==0){
            }
            if (datas.data!!.list[0].map_level.equals("region")){
                when(type){
                    1->newreginBean=datas.data!!.list
                    2->oldreginBean=datas.data!!.list
                    3->rentreginBean=datas.data!!.list}
            }
        }
          }.flatMap { t -> Observable.fromIterable(t) }
                .subscribe(object : ErrorHandleSubscriber<HomeBean>(rxErrorHandler) {
            override fun onNext(home: HomeBean) {
                if (home.map_level.equals("region")){
                    maptype=1
                    mRootView.addAreMarker(home)
                }else{
                    maptype=2
                    if (maphomeBeens.size==0||maphomeBeens.size>=100){
                        maphomeBeens.clear()
                        mRootView.clearMarker()
                    }
                    if (!maphomeBeens.contains(home.id)){
                        maphomeBeens.add(home.id)
                        mRootView.addHomeMarker(home)
                    }
                }
            }
        })
        builder = null
    }

    fun clearMapHome(){
        maphomeBeens.clear()
    }
    fun newArea(){
        type=1
        mRootView.clearMarker()
        if (newreginBean==null){
            socketSendMsg(ReqmapChangeBean(currentCity.lon,currentCity.lat,1,10,12.toFloat(),"xinfang",currentCity.id))
        }else{
            Observable.fromIterable(newreginBean).subscribe(Consumer { t ->  run{
                mRootView.addAreMarker(t)
                maptype=1
            } })
        }

    }
    fun oldArea(){
        type=2
        mRootView.clearMarker()
        if(oldreginBean==null){
            socketSendMsg(ReqmapChangeBean(currentCity.lon,currentCity.lat,1,10,12.toFloat(),"ershoufang",currentCity.id))
        }else{
            Observable.fromIterable(oldreginBean).subscribe(Consumer { t ->  run{
                mRootView.addAreMarker(t)
                maptype=1
            } })
        }

    }

    fun locationcitydata(type:Int){
        if (AppKey.bdLocation!!.longitude==null)return
        mRootView.clearMarker()
            when(type){
                1->socketSendMsg(ReqmapChangeBean(AppKey.bdLocation!!.longitude,AppKey.bdLocation!!.latitude,1,10,14.toFloat(),"xinfang",currentCity.id))
                2->socketSendMsg(ReqmapChangeBean(AppKey.bdLocation!!.longitude,AppKey.bdLocation!!.latitude,1,10,14.toFloat(),"ershoufang",currentCity.id))
                3->socketSendMsg(ReqmapChangeBean(AppKey.bdLocation!!.longitude,AppKey.bdLocation!!.latitude,1,10,14.toFloat(),"zufang",currentCity.id))
            }

    }
    fun rentArea(){
        type=3
        mRootView.clearMarker()
        if (rentreginBean==null){
            socketSendMsg(ReqmapChangeBean(currentCity.lon,currentCity.lat,1,10,12.toFloat(),"zufang",currentCity.id))
        }else{
            Observable.fromIterable(rentreginBean).subscribe(Consumer { t ->  run{
                mRootView.addAreMarker(t)
                maptype=1
            } })
        }
    }
   fun location(zoom:Int){
       if (AppKey.bdLocation==null){
           mRootView.setMylocationData(currentCity.lat,currentCity.lon,zoom)
       }else{
           if (AppKey.bdLocation!!.city.isNullOrEmpty()){
               if (currentCity==null)return
               mRootView.setMylocationData(currentCity.lat,currentCity.lon,zoom)
               mRootView.setZoomVisiable(false)
               return
           }
          if (AppKey.bdLocation!!.city.contains(currentCity.city)){
              mRootView.setMylocationData(AppKey.bdLocation!!.latitude,AppKey.bdLocation!!.longitude,14)
              mRootView.setZoomVisiable(true)
          }else{
              mRootView.setMylocationData(currentCity.lat,currentCity.lon,zoom)
              mRootView.setZoomVisiable(false)
          }
       }

   }
    fun initRxsoket(){
        socket.socketStatusListener()
                .subscribeOn(Schedulers.newThread())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe { socketStatus ->run{
                    if (socketStatus==RxSocket.SocketStatus.DIS_CONNECT){
                        if (mRootView!=null){
                            socketConnect()
                        }

                    }
                    Timber.d("socketStatus:" + socketStatus.name)
                }  }

    }
    override fun onDestroy() {
        socket.disConnect().subscribe({t -> if (t) Timber.d("断开成功")})
        super.onDestroy()
    }

    fun getmapRenthome(reginid:String,name :String){
        mModel.getRentlist(Reqmaphomelist(reginid,name,null)).compose(RxUtils.applySchedulers(mRootView))
                .subscribe(object :ErrorHandleSubscriber<BaseData<BaseListData<HomeBean>>>(rxErrorHandler){
                    override fun onNext(t: BaseData<BaseListData<HomeBean>>) {
                        mRootView.showpopListview(t,name)
                    }

                })
    }
    fun getmapOldhome(reginid:String,name :String){
        mModel.getershoulist(Reqmaphomelist(reginid,name,null)).compose(RxUtils.applySchedulers(mRootView))
                .subscribe(object :ErrorHandleSubscriber<BaseData<BaseListData<HomeBean>>>(rxErrorHandler){
                    override fun onNext(t: BaseData<BaseListData<HomeBean>>) {
                        mRootView.showpopListview(t,name)
                    }

                })
    }

    fun getBase64(str: String?): String {
        var result = ""
        if (str != null) {
            try {
//                Charsets.UTF_8
                result = Base64.encodeToString(str.toByteArray(Charsets.UTF_8),Base64.NO_WRAP)
            } catch (e: UnsupportedEncodingException) {
                e.printStackTrace()
            }

        }
        return result
    }
}